package com.heny.demo.handler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;

import java.sql.*;

/**
 * @author yaonn
 * @date 2025/9/1123:37
 * @Description
 */
@MappedTypes({Geometry.class, Point.class, LineString.class, Polygon.class})
public class GeometryTypeHandler extends BaseTypeHandler<Geometry> {
    private final GeometryFactory geometryFactory = new GeometryFactory();

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Geometry geometry, JdbcType jdbcType) throws SQLException {
        if (geometry == null) {
            preparedStatement.setNull(i, Types.OTHER);
        } else {
            // 转换为WKT格式存储
            preparedStatement.setString(i, geometry.toText());
        }
    }

    @Override
    public Geometry getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return parseGeometry(resultSet.getString(s));
    }

    @Override
    public Geometry getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return parseGeometry(resultSet.getString(i));
    }

    @Override
    public Geometry getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return parseGeometry(callableStatement.getString(i));
    }

    private Geometry parseGeometry(String wkt) {
        if (wkt == null || wkt.isEmpty()) {
            return null;
        }

        try {
            // 使用JTS的WKTReader解析几何对象
            WKTReader reader = new WKTReader(geometryFactory);
            return reader.read(wkt);
        } catch (ParseException e) {
            throw new RuntimeException("Failed to parse geometry from WKT: " + wkt, e);
        }
    }
}
